#!/usr/bin/env python3
import sys
import re
import html
from urllib import request, parse

apikey = 'EABB82DCE066D8062F7692D133A7A711'
# regex used in direct visit
pat1 = re.compile('<li class="clearfix">.*?<span class="prop">(.*?)</span>.*?<p>(.*?)</p>', re.S)
# regex used in api visit
pat2 = re.compile('<pos>(.*?)</pos>.*?<acceptation>(.*?)</acceptation>', re.S)

def connect_and_getdata(url):
    req = request.Request(url)
    page = None
    with request.urlopen(url) as req:
        if req.getcode()//100 != 2.:
            raise RuntimeError("Connection fails: %s!" % req.getcode())
        page = req.read().decode('utf-8')

    if page:
        return page
    else:
        raise RuntimeError("Unknown error.")

def search_word_general(word):
    if not word:
        raise IOError('Invalid word: %s!' % word)
    url = parse.urljoin('http://www.iciba.com/', word)
    page = connect_and_getdata(url)

    myitem = pat1.findall(page)
    if myitem:
        meanings = []
        for it in myitem:
            wt = it[0]
            mn = ''.join(it[1].replace('<span>', '').replace('</span>', '').split())
            meanings.append((wt, mn))
        return word, meanings
    else:
        return word, None

def search_word_api(word):
    if not word:
        raise IOError('Invalid word: %s!' % word)
    keywords = {'w': word, 'key': apikey}
    url = 'http://dict-co.iciba.com/api/dictionary.php?' + parse.urlencode(keywords)
    page = connect_and_getdata(url)

    myitem = pat2.findall(page)
    if myitem:
        meanings = []
        for it in myitem:
            wt = it[0]
            mn = it[1].strip()
            meanings.append((wt, mn))
        return word, meanings
    else:
        return word, None

def print_meanings(word, meanings):
    if meanings:
        print("\033[1;31m%s:\033[0m"%word)
        for it in meanings:
            wt, mn = it
            if wt:
                print('\033[1;34m%s\033[0m %s' % (wt, html.unescape(mn)))
            else:
                print(html.unescape(mn))
    else:
        print('Do not find "\033[1;31m%s\033[0m"!' %word)

if __name__ == '__main__':
    word = ' '.join(sys.argv[1:])
    print_meanings(*search_word_api(word))
